package com.cskaoyan.javase.array._1use._2basic;

/**
 * 数组的基本操作
 * 我们之前一直在讲,创建数组,给数组开辟存储单元
 * 那么这个操作过程,是在什么地方进行的呢?
 *      是在JVM当中进行的,是在JVM内存中进行的.
 *
 * @since 11:28
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 动态初始化一个int数组
        /*
            首先这里是定义了一个局部变量数组
            左边是数组的声明，右边是数组的初始化

            该数组变量是一个局部变量
            所以数组声明中，数组名这一个部分应该存储在方法的栈帧中
            也就是说arr是一个局部变量，它将直接存储在方法的栈帧中

            右边的初始化使用了new关键字
            new关键字表示在堆上创建对象

            所以：
            数组是典型的引用数据类型
            创建了一个数组局部变量，就意味着：
                a.首先在方法栈帧中开辟空间，存储它的"数组名"
                    称之为"引用数据类型的引用"
                b.然后在堆上开辟空间,创建数组对象
                    这就是"引用数据类型的对象"
            一个引用数据类型变量,实际上会分成两个部分:
                引用 + 对象

            对于一个引用数据类型而言,对象才是它的实质
            比如一个数组引用数据类型变量,对象是它的存储元素的存储空间
            但是没有办法直接访问实质,而是必须通过引用间接访问堆上的对象

            那么栈上的引用如何和堆上的对象产生联系呢?
            栈上引用通过存储堆上对象的地址,和堆上的对象产生联系
            也就是说,引用中存的是对象的地址.
         */
        int[] arr = new int[3];
        /*
           [I@1540e19d
           解释:
           "["表示这是一个一维数组
           "I"表示数组的类型是int类型
           1540e19d 是一个十六进制数
                这个十六进制数,可以近似看成堆上对象的地址值
            这个值是通过计算堆上对象的地址而得出来的
        */
        System.out.println(arr);
        System.out.println(arr.length);
        // int类型数组,动态初始化,元素具有默认值0
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        arr[0] = 100;
        System.out.println(arr[0]);
        /*
            修改元素的取值,并不会影响对象本身
            在Java当中,把修改对象中元素(属性)的取值
            称之为"改变对象的状态"
            改变对象的状态显然不会改变对象本身
           */
        System.out.println(arr);
        // 数组对象的长度一旦创建,就无法改变了
        System.out.println(arr.length);

        /*
            数组长度不可变指的是数组对象在堆上一旦被创建
            那么除非销毁它,否则它的长度永远不变
            对象不可变,但是引用是可变的
            引用仍然能够指向新的对象,新的数组对象可能长度就不一样了
         */
        arr = new int[10];
        // arr = new double[1];
        System.out.println(arr.length);
    }
}
